package com.vhall.component.service.notice.impl;

import cn.hutool.core.date.LocalDateTimeUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.google.common.collect.Maps;
import com.vhall.component.dao.notice.NoticesMapper;
import com.vhall.component.entity.notice.NoticesEntity;
import com.vhall.component.entity.notice.vo.NoticeListRspVo;
import com.vhall.component.entity.notice.vo.NoticeListVO;
import com.vhall.component.entity.notice.vo.RedPacketNoticeVo;
import com.vhall.component.entity.notice.vo.SendNoticeReqVo;
import com.vhall.component.entity.room.dto.RoomJoinsEntityDTO;
import com.vhall.component.entity.room.dto.RoomsEntityDTO;
import com.vhall.component.framework.common.exception.BusinessException;
import com.vhall.component.plugin.common.constant.RoomConstant;
import com.vhall.component.plugin.common.exception.BizErrorCode;
import com.vhall.component.plugin.core.service.PaasService;
import com.vhall.component.service.notice.NoticesService;
import com.vhall.component.service.room.RoomInnerService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.HashMap;
import java.util.Map;

/**
 * @author xianglei
 * @date 2021/6/9 16:38
 */
@Slf4j
@Service
public class NoticeServiceImpl extends ServiceImpl<NoticesMapper, NoticesEntity> implements NoticesService {

    @Autowired
    private NoticesMapper noticesMapper;

    @Autowired
    private RoomInnerService roomInnerService;

    @Autowired
    private PaasService paasService;

    @Override
    public NoticeListRspVo list(NoticeListVO reqVO) {

        LambdaQueryWrapper<NoticesEntity> wrapper = Wrappers.lambdaQuery();
        wrapper.eq(reqVO.getRoomId() != null, NoticesEntity::getRoomId, reqVO.getRoomId())
                .eq(NoticesEntity::getType, 0)
                .ge(reqVO.getStartTime() != null, NoticesEntity::getCreatedAt, reqVO.getStartTime())
                .orderByDesc(NoticesEntity::getId);
        int currPage = reqVO.getCurrPage() == null ? 1 : reqVO.getCurrPage();
        int pageSize = reqVO.getPageSize() == null ? 20 : reqVO.getPageSize();
        Page<NoticesEntity> page = new Page<>(currPage, pageSize);
        page = noticesMapper.selectPage(page, wrapper);
        return new NoticeListRspVo(page);
    }


    @Override
    @Transactional(rollbackFor = Exception.class)
    public JSONObject sendNotices(Integer accountId, SendNoticeReqVo reqVo) {
        RoomJoinsEntityDTO joinUser = getCurrentJoinUser(reqVo.getRoomId(), accountId);
        return sendNotice(reqVo.getRoomId(), reqVo.getContent(), joinUser.getAccountId(), reqVo.getType());
    }

    @Override
    public JSONObject sendNotice(String roomId, String content, Integer accountId, String type) {
        type = type == null ? "text" : type;
        HashMap<String, Object> jsonContents = Maps.newHashMap();
        jsonContents.put("type", type);
        jsonContents.put("content", content);
        content = JSON.toJSONString(jsonContents);

        NoticesEntity entity = new NoticesEntity();

        entity.setAppId(paasService.getAppId());
        entity.setRoomId(roomId);
        entity.setAccountId(accountId);
        entity.setContent(content);
        entity.setRedPacketUuid("");
        entity.setCreatedAt(LocalDateTime.now());
        entity.setUpdatedAt(LocalDateTime.now());
        noticesMapper.insert(entity);

        String body = buildMsgBody("room_announcement", accountId, content, LocalDateTime.now());
        RoomsEntityDTO byRoomId = roomInnerService.getRoomInfo(roomId);
        return paasService.sendMessage(byRoomId.getChannelId(), body);
    }


    @Override
    public NoticesEntity addRpNotice(RedPacketNoticeVo vo) {
        NoticesEntity entity = new NoticesEntity();
        entity.setAccountId(vo.getAccountId());
        entity.setType(1);
        entity.setRedPacketUuid(vo.getRpUuid());
        entity.setRoomId(vo.getRoomId());
        entity.setAppId(paasService.getAppId());
        Map<String, Object> content = new HashMap<>(4);
        content.put("type", "redpacket");
        content.put("content", vo.getContent());
        entity.setContent(JSON.toJSONString(content));
        entity.setCreatedAt(LocalDateTime.now());
        entity.setUpdatedAt(LocalDateTime.now());
//        noticesMapper.insert(entity);
        return entity;
    }

    @Override
    public NoticesEntity getRpNotice(String rpUuid) {
        LambdaQueryWrapper<NoticesEntity> wrapper = Wrappers.lambdaQuery();
        wrapper.eq(NoticesEntity::getRedPacketUuid, rpUuid)
                .last("limit 1;");
        return noticesMapper.selectOne(wrapper);
    }

    @Override
    public NoticesEntity updateRpNotice(RedPacketNoticeVo vo) {

        NoticesEntity entity = new NoticesEntity();
        entity.setAccountId(vo.getAccountId());
        entity.setRedPacketUuid(vo.getRpUuid());
        entity.setRoomId(vo.getRoomId());
        entity.setAppId(paasService.getAppId());
        entity.setContent(vo.getContent());
        entity.setUpdatedAt(LocalDateTime.now());

        UpdateWrapper<NoticesEntity> where = new UpdateWrapper<>();
        where.set("red_packet_uuid", vo.getRpUuid());
        noticesMapper.update(entity, where);
        return entity;
    }


    /**
     * 构造body
     *
     * @param
     * @return
     */
    private String buildMsgBody(String type, Integer roomJoinId, String roomAnnouncementText, LocalDateTime pushTime) {
        JSONObject jsonObject = new JSONObject();
        jsonObject.put("type", type);
        jsonObject.put("room_join_id", roomJoinId);
        jsonObject.put("room_announcement_text", roomAnnouncementText);
        jsonObject.put("push_time", LocalDateTimeUtil.formatNormal(pushTime));
        return jsonObject.toJSONString();
    }

    RoomJoinsEntityDTO getCurrentJoinUser(String roomId, Integer thirdId) {
        RoomJoinsEntityDTO joinUser = roomInnerService.getCurrentJoinUserByThirdId(roomId, thirdId);
        if (!joinUser.getRoleName().equals(RoomConstant.ASSISTANT)
                && !joinUser.getRoleName().equals(RoomConstant.HOST)) {
            throw new BusinessException(BizErrorCode.BIZ_NO_PERMISSION);
        }
        return joinUser;
    }

}
